package com.atguigu.tingshu.common.login;

import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.rmi.ServerException;

@Component
@Aspect

/*
**
*环绕通知有四个特征:
*1.方法必须返回object对象
*2.方法必须有ProceedingJoinPoint形参*3.方法需要抛出Throwable异常
★4.必须手动执行目标方法
*/


public class GuiGuLoginAspect {
    @Resource
    RedisTemplate redisTemplate;


    @Around("@annotation(guiGuLogin)")
    public Object Login(ProceedingJoinPoint joinPoint, GuiGuLogin guiGuLogin) throws Throwable {

        /*
        获取token，并根据token获取登录信息放入ThreadLocal中l/1.获取request对象:AuthcontextHolder
         */
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //2 从请求头获取token
        String token = request.getHeader("token");
        UserInfoVo userInfoVo = null;
        // 3 判断token是否为空 若不为空去Redis中查询登录信息
        if (StringUtils.isNotBlank(token)) {
            userInfoVo = (UserInfoVo) redisTemplate.opsForValue().get(RedisConstant.USER_LOGIN_KEY_PREFIX + token);
        }

        // 判断Redis中是否存在用户登录信息
        // 传递到后续业务（threadLoad）
        if (userInfoVo != null) {
            AuthContextHolder.setUserId(userInfoVo.getId());
            AuthContextHolder.setUsername(userInfoVo.getNickname());
        }
        if (userInfoVo == null && guiGuLogin.required()) {
            throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
        }

//执行目标方法
        Object result = joinPoint.proceed(joinPoint.getArgs());
//        System.out.println("z执行后");

        // 释放threadload 中的登录状态 防止信息泄露！！！
            AuthContextHolder.removeUserId();
            AuthContextHolder.removeUsername();
        return result;
    }

}
